#include <unistd.h>
#include "Sock.hpp"
using namespace std;
static const int defaultport = 8081;
static const int fdnum = sizeof(fd_set) * 8;
static const int defaultfd = -1;
class SelectServer
{
public:
    SelectServer(uint16_t port = defaultport) : _port(port), _listensock(-1), _fdarry(nullptr)
    {
    }

    void initserver()
    {
        _listensock = Sock::Socket();   // 创建套接字
        Sock::Bind(_listensock, _port); // bind信息
        Sock::Listen(_listensock);      // 把sock设置为监听状态
        // cout<<"fd_set size: "<<sizeof(fd_set)<<endl;
        _fdarry = new int[fdnum]; // 保存fd的数组
        for (int i = 0; i < fdnum; i++)
        {
            _fdarry[i] = defaultfd;
        }
        _fdarry[0] = _listensock;
    }

void Print()
{
    cout<<"fd list: ";
    for(int i=0;i<fdnum;i++)
    {
        if(_fdarry[i]!=defaultfd)
        cout<<_fdarry[i]<<" ";
    }
    cout<<endl;
}
    void handleract(fd_set&rfd)
    {
        if(FD_ISSET(_listensock,&rfd))
        {
            char buffer[1024];
        uint16_t clientport;
        string clientip;
        int sock = Sock::Accpet(_listensock, &clientip, &clientport); // 获取sock
        if (sock < 0)
        {
            cout << "Sock::Accept err " << endl;
            return;
        }
        cout << "get a new sock: " << sock << endl;
        int i=0;
        for(;i<fdnum;i++)
        {
            if(_fdarry[i]!=defaultfd)
            continue;
            else break;
        }
        if(i==fdnum)
        {
            cout<<"server is full,please wait"<<endl;
            close(sock);
        }
        _fdarry[i]=sock;
        FD_SET(_fdarry[i],&rfd);
        Print();
        }
        
    }

    void start()
    {
        for (;;)
        {
            fd_set rfd;
            FD_ZERO(&rfd); // 清空位图
            int maxfd = _fdarry[0];
            int i = 0;
            for (; i < fdnum; i++)
            {
                if(_fdarry[i]==defaultfd)
                continue;

                FD_SET(_fdarry[i],&rfd);
                maxfd=maxfd>_fdarry[i]?maxfd:_fdarry[i];//更新最大fd数
            }

            // struct timeval timeout={1,0};
            // int n=select(_listensock+1,&rfd,nullptr,nullptr,&timeout);
            int n = select(maxfd + 1, &rfd, nullptr, nullptr, nullptr); // 阻塞式
            switch (n)
            {
            case 0:
                cout << "timeout......" << endl;
                break;
            case -1:
                cout << "select err" << endl;
            default:
                cout << "get new link..." << endl;
                handleract(rfd);
                break;
            }
            sleep(1);
        }
    }

private:
    uint16_t _port;
    int _listensock;
    int *_fdarry;
};